// Header Protection
#ifndef _LISTENER_H_
#define _LISTENER_H_

// Include Files
#include "Event\EventArg.h"

// Forward Declarations
template< class eventarg_t > class CEvent;
class IListener;
class ABCNotification;

/////////////////////////////////////////////////////////////////////////////////////
// Classes derive from IListener to gain the ability to listen for events.
class IListener
{
protected:  // child methods

	IListener() : m_NotMutex(), m_lstNots() { }
	~IListener() { }

	// Register this listener for the event with the given event handler.
	// listener_t : template - the type of the derived listener class
	// eventarg_t : template - the type of the event argument
	// _rEvent : CEvent<eventarg_t> & - the event to listen for
	// _pHandler : void (listener_t::*)(eventarg_t &) - the event handler to call 
	//     when the event is raised
	template< class listener_t, class eventarg_t >
	inline void AddEventListener( 
		CEvent<eventarg_t> &_rEvent, void (listener_t::*_pHandler)(eventarg_t &) )
	{
		// add the registration to the event
		_rEvent.AddRegistration( (listener_t*)this, _pHandler);
	}

	// Unregister this listener from the event with the given event handler.
	// listener_t : template - the type of the derived listener class
	// eventarg_t : template - the type of the event argument
	// _rEvent : CEvent<eventarg_t> & - the event to stop listening for
	// _pHandler : void (listener_t::*)(eventarg_t &) - the event handler which was 
	//     used to listen for the event.
	template< class listener_t, class eventarg_t >
	inline void RemoveEventListener( 
		CEvent< eventarg_t > &_rEvent, void (listener_t::*_pHandler)(eventarg_t &) )
	{
		// remove the registration from the event
		_rEvent.RemoveRegistration( (listener_t*)this, _pHandler );
	}

	// Call the event handlers for each event which has been raised since the last 
	//     time this method was called. If this method is never called, event 
	//     handlers will never be called.
	void ProcessEvents();

private:    // ABCRegistration friend methods

	friend class ABCRegistration;

	// An event which this listener is registered for has been raised. Add a 
	//     notification to the queue to be processed.
	// _pNot : ABCNotification * - the notification to add to the queue
	inline void Raise( ABCNotification *_pNot )
	{
		// append the notification to the list
		m_NotMutex.Lock();
		m_lstNots.Append(_pNot);
		m_NotMutex.Unlock();
	}

private:    // data
	mutex_t                  m_NotMutex;
	list_t<ABCNotification*> m_lstNots;

private:    // dummy definitions
	IListener( IListener const & );
	IListener &operator =( IListener const & );
};

// Header Protection
#endif // _LISTENER_H_
